import * as THREE from 'three'
import createApp from '../../core'

function createExtrudeGeometry (dom: HTMLElement) {
  const { camera, scene, update, gui } = createApp(dom)
  camera.position.set(0, 0, 100)
  camera.lookAt(scene.position)

  const mesh = createExtrudeFromGeometry()
  mesh.position.set(-40, 0, 0)
  scene.add(mesh)

  const bufferMesh = createExtrudeFromBufferGeometry()
  bufferMesh.position.set(40, 0, 0)
  scene.add(bufferMesh)

  update((time: number) => {
    const angle = time / 2000
    mesh.rotation.set(angle, angle, 0)
    bufferMesh.rotation.set(angle, angle, 0)
  })

  function updateMeshs () {
    generateGeometry(mesh)
    generateGeometry(bufferMesh)
  }

  gui.add(data, 'steps', 0, 30, 1).onChange(updateMeshs)
  gui.add(data, 'depth', 0, 30).onChange(updateMeshs)
  gui.add(data, 'bevelEnabled').onChange(updateMeshs)
  gui.add(data, 'bevelThickness', 1, 10).onChange(updateMeshs)
  gui.add(data, 'bevelSize', 1, 10).onChange(updateMeshs)
  gui.add(data, 'bevelSegments', 1, 10, 1).onChange(updateMeshs)
}

const data = {
  steps: 2,
  depth: 16,
  bevelEnabled: true,
  bevelThickness: 1,
  bevelSize: 1,
  bevelSegments: 1
}

function createShape () {
  const shape = new THREE.Shape()
  shape.moveTo(0, 0)
  shape.lineTo(30, 0)
  shape.lineTo(30, 10)
  shape.lineTo(10, 10)
  shape.lineTo(10, 30)
  shape.lineTo(0, 30)
  shape.lineTo(0, 0)
  return shape
}

function createExtrudeFromGeometry () {
  const shape = createShape()
  const geometry = new THREE.ExtrudeGeometry(shape, data)
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true })
  const mesh = new THREE.Mesh(geometry, material)
  return mesh
}

function createExtrudeFromBufferGeometry () {
  const shape = createShape()
  const geometry = new THREE.ExtrudeBufferGeometry(shape, data)
  const material = new THREE.MeshNormalMaterial()
  const mesh = new THREE.Mesh(geometry, material)
  return mesh
}

function generateGeometry (mesh: THREE.Mesh) {
  const shape = createShape()
  const geometry = new THREE.ExtrudeBufferGeometry(shape, data)
  mesh.geometry.dispose()
  mesh.geometry = geometry
}

export {
  createExtrudeGeometry
}
